﻿//
// Name: Form1.cs
// Project: elektor HiD Temperature Modul
// Author: Michael Odenwald
// Creation Date: 10.05.2013 
//

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Win32;
using System.Net;
using System.Text.RegularExpressions;
using AppSettingsLib;
using System.Windows.Forms;

namespace WindowsApp
{
    enum MessageType { UsbComm, UsbError };

    public partial class Form1 : Form
    {
        // Create an instance of the USB reference device
        private usbDevice theUsbDevice;
        private String HiDKey = "SOFTWARE\\elektor\\Temperature Modul";

        AppSettingsManager settings = new AppSettingsManager();
        private UInt16 SeekNumberToCheck = 0;
        private string WebPageToUseb;
        private string SeekStringToUsb;
        private bool WebClientDownloadCompleteFlag = false;

        /// <summary>
        /// This is the application for the elektor USB HiD Temperature Modul with the 
        /// usbGenericHidCommunications class library for communication.  
        /// </summary>
        public Form1()
        {
            InitializeComponent();

            // Create the USB reference device object (passing VID and PID)
            theUsbDevice = new usbDevice(0x0C7D, 0x0011);

            // Add a listener for the Form closing event
            this.FormClosing += this.Form1_FormClosing;

            // Add a listener for usb events
            theUsbDevice.usbEvent += new usbDevice.usbEventsHandler(usbEvent_receiver);

            // Perform an initial search for the target device
            theUsbDevice.findTargetDevice();


        }


        #region Form events

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            RegistryKey HiDTempKey = Registry.CurrentUser.OpenSubKey(HiDKey);
            Int32 X;
            Int32 Y;

            if (SubKeyExist(HiDKey))
            {
                X = Convert.ToInt32(HiDTempKey.GetValue("X-Pos"));
                Y = Convert.ToInt32(HiDTempKey.GetValue("Y-Pos"));

                if ((X > 0) && (Y > 0)) // value are in visiable area?
                {
                    this.Location = new Point(X, Y);
                }
                else
                {
                    this.Location = new Point(10, 10);
                }
            }
            else
            {
                this.Location = new Point(10, 10); // no value in the registry, than using position 10, 10
            }

            WebPageToUseb = settings.UserSettings.Configs.config1.webPage;
            SeekStringToUsb = settings.UserSettings.Configs.config1.seekString;

            ControlsUpdate();

            WindowState = FormWindowState.Minimized;
            this.Hide();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            RegistryKey HiDTempKey = Registry.CurrentUser.CreateSubKey(HiDKey);

            if (((int)this.Location.X > 0) && ((int)this.Location.Y > 0)) // write only if Pos is in visiable area
            {
                // Write Values to the Subkey
                HiDTempKey.SetValue("X-Pos", this.Location.X.ToString());
                HiDTempKey.SetValue("Y-Pos", this.Location.Y.ToString());
            }

            settings.UserSettings.Save();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void mainFormResized(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
                Hide();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void maximizeMainForm(object sender, EventArgs e)
        {
            Show();
            WindowState = FormWindowState.Normal;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SeekStringInvalidOptionEv(object sender, EventArgs e)
        {
            this.SeekNumberCheckResOption.Visible = false;
            this.SeekStringValidOption.Visible = false;
            this.SeekStringInvalidOption.Visible = false;

            this.CheckStringOption.Visible = true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SeekStringValidOptionEv(object sender, EventArgs e)
        {
            this.SeekNumberCheckResOption.Visible = false;
            this.SeekStringValidOption.Visible = false;
            this.SeekStringInvalidOption.Visible = false;

            this.CheckStringOption.Visible = true;

            //if(!(this.SeekStringOption.Items.Contains(this.SeekStringOption.Text)))
            //{
            //    this.WebSiteOption.Items.Insert(0, this.WebSiteOption.Text);
            //    this.SeekStringOption.Items.Insert(0, this.SeekStringOption.Text);
            //}
            if ((settings.UserSettings.Configs.config1.webPage != this.WebSiteOption.Text) || 
                (settings.UserSettings.Configs.config1.seekString != this.SeekStringOption.Text))
            {
                WebSiteOption.Items[1] = settings.UserSettings.Configs.config3.webPage = settings.UserSettings.Configs.config2.webPage;
                SeekStringOption.Items[1] = settings.UserSettings.Configs.config3.seekString = settings.UserSettings.Configs.config2.seekString;

                WebSiteOption.Items[0] = settings.UserSettings.Configs.config2.webPage = settings.UserSettings.Configs.config1.webPage;
                SeekStringOption.Items[0] = settings.UserSettings.Configs.config2.seekString = settings.UserSettings.Configs.config1.seekString;

                WebPageToUseb = settings.UserSettings.Configs.config1.webPage = this.WebSiteOption.Text;
                SeekStringToUsb = settings.UserSettings.Configs.config1.seekString = this.SeekStringOption.Text;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void checkStringOption(object sender, MouseEventArgs e)
        {
            if (BackgroundCheckProgress.IsBusy != true)
            {
                this.CheckStringOption.Visible = false;
                CheckProgress.Visible = true;
                WebClientDownloadCompleteFlag = false;

                WebClient wc = new WebClient();
                Uri uri = new Uri(this.WebSiteOption.Text);

                wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(WebClientToCheck_DownloadCompleted);
                wc.DownloadStringAsync(uri);

                BackgroundCheckProgress.RunWorkerAsync();
            }

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void autoStartOptionChanged(object sender, EventArgs e)
        {
            settings.UserSettings.Configs.autoStart = this.AutoStartOption.Checked;

            RegistryKey rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);

            if (this.AutoStartOption.Checked == true)
            {
                rkApp.SetValue(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, Application.ExecutablePath.ToString());
            }
            else
            {
                rkApp.DeleteValue(System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, false);
            }
        }

        #endregion

        #region Async events

        /// <summary>
        /// 
        /// </summary>
        /// <param name="o"></param>
        /// <param name="e"></param>
        private void usbEvent_receiver(object o, EventArgs e)
        {
            // Check the status of the USB device and update the form accordingly
            if (theUsbDevice.isDeviceAttached)
            {
                // Device is currently attached

                // Update the status label
                this.toolStripStatusLabel1.Text = "USB Device is attached";
                DisplayMessage(MessageType.UsbComm, "USB Device is attached");

                // enable the timer
                this.timer1.Interval = 1000;
                this.timer1.Enabled = true;
            }
            else
            {
                // Device is currently unattached

                // Update the status label
                this.toolStripStatusLabel1.Text = "USB Device is detached";
                DisplayMessage(MessageType.UsbComm, "USB Device is detached");

                // disable the timer
                this.timer1.Enabled = false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer1_Tick(object sender, EventArgs e)
        {
            this.timer1.Interval = 60000;

            WebClient wc = new WebClient();
            Uri uri = new Uri(this.WebSiteOption.Text);

            wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(WebClientToUsb_DownloadCompleted);

            wc.DownloadStringAsync(uri);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BgCheckProgress_changed(object sender, ProgressChangedEventArgs e)
        {
            CheckProgress.Value = e.ProgressPercentage;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BgCheckProgress_completed(object sender, RunWorkerCompletedEventArgs e)
        {
            this.SeekNumberCheckResOption.Visible = true;
            this.SeekStringValidOption.Visible = true;
            this.SeekStringInvalidOption.Visible = true;

            this.SeekNumberCheckResOption.Text = SeekNumberToCheck.ToString();

            CheckProgress.Visible = false;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void BgCheckProgress_work(object sender, DoWorkEventArgs e)
        {
            for (int i = 1; (i <= 100); i++)
            {
                if ((WebClientDownloadCompleteFlag == true))
                {
                    System.Threading.Thread.Sleep(10);
                }
                else if (i < 50)
                {
                    System.Threading.Thread.Sleep(250);
                }
                else
                {
                    System.Threading.Thread.Sleep(1000);
                }
                BackgroundCheckProgress.ReportProgress(i);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebClientToUsb_DownloadCompleted(Object sender, DownloadStringCompletedEventArgs e)
        {
            try
            {
                UInt16 VisitorsCount = 0;
                string htmlString = (string)e.Result;

                Regex rgx = new Regex(SeekStringToUsb + @"\d+");
                string resultString = rgx.Match(htmlString).Value;

                string result = resultString.Replace(SeekStringToUsb, "");

                VisitorsCount = Convert.ToUInt16(result, 10);

                bool tval = theUsbDevice.SendDataToAtmel(VisitorsCount);
            }
            catch (Exception)
            {
                DisplayMessage(MessageType.UsbError, e.Error.ToString());
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void WebClientToCheck_DownloadCompleted(Object sender, DownloadStringCompletedEventArgs e)
        {
            string htmlString = (string)e.Result;

            Regex rgx = new Regex(this.SeekStringOption.Text + @"\d+");
            string resultString = rgx.Match(htmlString).Value;

            string result = resultString.Replace(this.SeekStringOption.Text, "");

            SeekNumberToCheck = Convert.ToUInt16(result, 10);

            WebClientDownloadCompleteFlag = true;
        }
        #endregion

        #region Other functions

        /// <summary>
        /// 
        /// </summary>
        /// <param name="Subkey"></param>
        /// <returns></returns>
        private bool SubKeyExist(string Subkey)
        {
            // Check if a Subkey exist
            RegistryKey myKey = Registry.CurrentUser.OpenSubKey(Subkey);
            if (myKey == null)
                return false;
            else
                return true;
        }

        /// <summary>
        /// 
        /// </summary>
        private void ControlsUpdate()
        {
            this.AutoStartOption.Checked = settings.UserSettings.Configs.autoStart;

            this.WebSiteOption.Text = settings.UserSettings.Configs.config1.webPage;
            this.SeekStringOption.Text = settings.UserSettings.Configs.config1.seekString;

            this.WebSiteOption.Items.Add(settings.UserSettings.Configs.config2.webPage);
            this.SeekStringOption.Items.Add(settings.UserSettings.Configs.config2.seekString);
            this.WebSiteOption.Items.Add(settings.UserSettings.Configs.config3.webPage);
            this.SeekStringOption.Items.Add(settings.UserSettings.Configs.config3.seekString);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <param name="text"></param>
        private void DisplayMessage(MessageType type, string text)
        {
            this.notifyIcon1.BalloonTipIcon = ToolTipIcon.Info;
            

            try
            {
                this.notifyIcon1.ShowBalloonTip(10000);
            }
            catch (Exception)
            {
                
            }

            switch (type)
            {
                case MessageType.UsbComm:
                    {
                        this.notifyIcon1.BalloonTipTitle = "Usb communication";
                        this.notifyIcon1.BalloonTipText = text;

                        break;
                    }
                case MessageType.UsbError:
                    {
                        this.notifyIcon1.BalloonTipTitle = "Usb error";
                        this.notifyIcon1.BalloonTipText = text;

                        break;
                    }
            }
        }

        #endregion

    }
}
